// locutor command line client
// (c) 2009, Normen Müller, normen.mueller@gmail.com  
// $Id: SVNBook.scala 26 2009-11-10 14:57:05Z normen.mueller $
package locutor.cli.eq

import scalaxx.Views._
import scala.xml.{Node}

/** An equivalence system for SVNBook.
 * 
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.2 */
private [locutor] object SVNBookEquivs extends scaup.eq.EquivalenceSystem[Node] {
  private val labels = Set(
    "appendix", "attribution", "author", "authorgroup",
    "blockquote", "book", "bookinfo",
    "chapter", "citetitle", "command", "computeroutput", "copyright", 
    "edition", "editor", "email", "emphasis", "entry", "example",
    "figure", "filename", "firstname", "firstterm", "footnote", "function",
    "graphic", "guimenu", "guimenuitem",
    "holder",
    "index", "indexterm", "isbn", "itemizedlist",
    "legalnotice", "listitem", "literal",
    "note",
    "option", "orderedlist",
    "pagenums", "para", "parameter", "preface", "prefaceinfo", "primary", "programlisting", "pubdate",
    "quote",
    "refentry", "refname", "refnamediv", "refpurpose", "refsect1", "replaceable", "row",
    "screen", "secondary", "sect1", "sect2", "sect3", "sect4", "sidebar", "subtitle", "surname",
    "table", "tbody", "term", "tertiary", "tgroup", "thead", "tip", "title",
    "ulink", "uri", "userinput",
    "variablelist", "varlistentry",
    "warning",
    "xref",
    "year"
  )
  
  override def equiv[S <: Node](l: S, r: S): Boolean =
    if((labels contains l.qname) && (labels contains r.qname))
      eq_name(l, r) || eq_attrs(l, r) || eq_content(l, r) || eq_deep(l, r)
    else false
        
  override def ordered[S <: Node](l: S): Boolean = !(Set("author", "holder", "varlistentry") contains l.qname)
  
  private def eq_name(l: Node, r: Node) = (l.qname == r.qname) && (Set(
    "authorgroup",
    "bookinfo",
    "copyright",
    "editor",
    "footnote",
    "indexterm", "itemizedlist",
    "legalnotice", "listitem",
    "note",
    "orderedlist",
    "para", "prefaceinfo", "programlisting",
    "screen",
    "tbody", "thead", "tip",
    "variablelist", "varlistentry",
    "warning"
  ) contains l.qname)
  
  private def eq_attrs(l: Node, r: Node) = (l.qname == r.qname) && ((Set(
    "appendix",
    "book",
    "chapter",
    "example",
    "figure",
    "graphic",
    "index",
    "preface",
    "refentry", "refname", "refnamediv", "refpurpose", "refsect1", "replaceable",
    "sect1", "sect2", "sect3", "sect4", "sidebar",
    "table", "tgroup",
    "ulink",
    "xref"
  ) contains l.qname) && (l.attributes forall (_ containedIn r.attributes)))
  
  private def eq_content(l: Node, r: Node) = (l.qname == r.qname) && ((Set(
    "attribution", "author",
    "blockquote", 
    "citetitle", "command", "computeroutput",
    "edition", "email", "emphasis", "entry",
    "firstname", "filename", "firstterm", "function",
    "guimenu", "guimenuitem",
    "holder",
    "isbn",
    "literal",
    "option",
    "pagenums", "pubdate", "parameter", "primary",
    "quote",
    "row", "term", "tertiary",
    "subtitle", "surname", "secondary",
	"title",
    "uri", "userinput",
    "year"	 
  ) contains l.qname) && equiv(l.child,r.child))
  
  private def eq_deep(l: Node, r: Node) = (l.qname == r.qname) && super.equiv(l,r)
  
}
